<!DOCTYPE html>
<html lang=zh>
<head>
  <meta charset="utf-8">
  
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
  <meta name="renderer" content="webkit">
  <meta http-equiv="Cache-Control" content="no-transform" />
  <meta http-equiv="Cache-Control" content="no-siteapp" />
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="format-detection" content="telephone=no,email=no,adress=no">
  <!-- Color theme for statusbar -->
  <meta name="theme-color" content="#000000" />
  <!-- 强制页面在当前窗口以独立页面显示,防止别人在框架里调用页面 -->
  <meta http-equiv="window-target" content="_top" />
  
  
  <title>js面试题 | 雨落</title>
  <meta name="description" content="1、防抖和节流1234567891011121314151617181920212223242526272829303132333435363738&#x2F;&#x2F; 防抖：当持续触发一个事件时，在n秒内，事件没有再次触发，此时才会执行回调；如果n秒内，又触发了事件，就重新计时&#x2F;&#x2F; 使用场景：登录按钮，提交按钮，防止不断请求资源；监听resize触发时， 不断的调整浏览器窗口大小会不断触发resize，使用防抖">
<meta property="og:type" content="article">
<meta property="og:title" content="js面试题">
<meta property="og:url" content="https://gitee.com/Yu-Luoboke/2023/11/29/js%E9%9D%A2%E8%AF%95%E9%A2%98/index.html">
<meta property="og:site_name" content="雨落">
<meta property="og:description" content="1、防抖和节流1234567891011121314151617181920212223242526272829303132333435363738&#x2F;&#x2F; 防抖：当持续触发一个事件时，在n秒内，事件没有再次触发，此时才会执行回调；如果n秒内，又触发了事件，就重新计时&#x2F;&#x2F; 使用场景：登录按钮，提交按钮，防止不断请求资源；监听resize触发时， 不断的调整浏览器窗口大小会不断触发resize，使用防抖">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2023-11-29T15:37:30.000Z">
<meta property="article:modified_time" content="2023-11-29T16:03:26.034Z">
<meta property="article:author" content="lianghongming">
<meta name="twitter:card" content="summary">
  <!-- Canonical links -->
  <link rel="canonical" href="https://gitee.com/Yu-Luoboke/2023/11/29/js%E9%9D%A2%E8%AF%95%E9%A2%98/index.html">
  
    <link rel="alternate" href="/atom.xml" title="雨落" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png" type="image/x-icon">
  
  
<link rel="stylesheet" href="/blog/css/style.css">

  
  
  
  
<meta name="generator" content="Hexo 5.2.0"></head>


<body class="main-center" itemscope itemtype="http://schema.org/WebPage">
  <header class="header" itemscope itemtype="http://schema.org/WPHeader">
  <div class="slimContent">
    <div class="navbar-header">
      
      
      <div class="profile-block text-center">
        <a id="avatar" href="http://yu-luoboke.gitee.io/blog" target="_blank">
          <img class="img-circle img-rotate" src="/blog/images/avatar.jpg" width="200" height="200">
        </a>
        <h2 id="name" class="hidden-xs hidden-sm">雨落</h2>
        <h3 id="title" class="hidden-xs hidden-sm hidden-md">前端开发-奋斗青年</h3>
        <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i> GuangZhou, China</small>
      </div>
      
      <div class="search" id="search-form-wrap">

    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="搜索" />
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i class="icon icon-search"></i></button>
            </span>
        </div>
    </form>
    <div class="ins-search">
  <div class="ins-search-mask"></div>
  <div class="ins-search-container">
    <div class="ins-input-wrapper">
      <input type="text" class="ins-search-input" placeholder="想要查找什么..." x-webkit-speech />
      <button type="button" class="close ins-close ins-selectable" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
    </div>
    <div class="ins-section-wrapper">
      <div class="ins-section-container"></div>
    </div>
  </div>
</div>


</div>
      <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
    </div>
    <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
      <ul class="nav navbar-nav main-nav menu-highlight">
        
        
        <li class="menu-item menu-item-home">
          <a href="/blog/.">
            
            <i class="icon icon-home-fill"></i>
            
            <span class="menu-title">首页</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-archives">
          <a href="/blog/archives">
            
            <i class="icon icon-archives-fill"></i>
            
            <span class="menu-title">归档</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-categories">
          <a href="/blog/categories">
            
            <i class="icon icon-folder"></i>
            
            <span class="menu-title">分类</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-tags">
          <a href="/blog/tags">
            
            <i class="icon icon-tags"></i>
            
            <span class="menu-title">标签</span>
          </a>
        </li>
        
      </ul>
      
	
    <ul class="social-links">
    	
        <li><a href="http://yu-luoboke.gitee.io/blog" target="_blank" title="Github" ><i class="icon icon-github"></i></a></li>
        
    </ul>

    </nav>
  </div>
</header>

  
    <aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">公告</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content">
                <p>欢迎交流与分享经验!</p>
            </div>
        </div>
    </div>
</div>

    
      
  <div class="widget">
    <h3 class="widget-title">分类</h3>
    <div class="widget-body">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Git/">Git</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/HTML-CSS/">HTML + CSS</a><span class="category-list-count">7</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/JVM%EF%BC%88Java%E8%99%9A%E6%8B%9F%E6%9C%BA%EF%BC%89-%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E7%AE%97%E6%B3%95/">JVM（Java虚拟机）-垃圾回收算法</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Node/">Node</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Project/">Project</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/React/">React</a><span class="category-list-count">4</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/SVN/">SVN</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Vue-typescript/">Vue-typescript</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/gitee/">gitee</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/iOS/">iOS</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/js/">js</a><span class="category-list-count">12</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/vue/">vue</a><span class="category-list-count">13</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/web-serve%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E6%9C%8D%E5%8A%A1%E5%99%A8/">web serve静态资源服务器</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/webpack/">webpack</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E5%89%8D%E7%AB%AF%E8%87%AA%E5%8A%A8%E5%8C%96/">前端自动化</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/">小程序</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E7%A7%BB%E5%8A%A8%E7%AB%AF/">移动端</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E7%BB%8F%E9%AA%8C/">经验</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a><span class="category-list-count">4</span></li></ul>
    </div>
  </div>


    
      

    
      
    
      
  <div class="widget">
    <h3 class="widget-title">归档</h3>
    <div class="widget-body">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2024/04/">四月 2024</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2023/11/">十一月 2023</a><span class="archive-list-count">8</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2023/09/">九月 2023</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/12/">十二月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/08/">八月 2022</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/07/">七月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/06/">六月 2022</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/04/">四月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/01/">一月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/12/">十二月 2021</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/11/">十一月 2021</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/10/">十月 2021</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/04/">四月 2021</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/03/">三月 2021</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/02/">二月 2021</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/01/">一月 2021</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2020/12/">十二月 2020</a><span class="archive-list-count">15</span></li></ul>
    </div>
  </div>


    
      
  <div class="widget">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget-body">
      <ul class="recent-post-list list-unstyled no-thumbnail">
        
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/HTML-CSS/">HTML + CSS</a>
              </p>
              <p class="item-title">
                <a href="/blog/2024/04/15/%E6%8B%96%E5%8A%A8%E5%92%8C%E7%82%B9%E5%87%BB%E5%BC%B9%E7%AA%97/" class="title">拖动和点击弹窗</a>
              </p>
              <p class="item-date">
                <time datetime="2024-04-15T12:22:06.000Z" itemprop="datePublished">2024-04-15</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/html%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">html面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:58:27.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/css%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">css面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:57:17.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/js%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">js面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:37:30.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:29:49.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
      </ul>
    </div>
  </div>
  

    
  </div>
</aside>

  
  
<main class="main" role="main">
  <div class="content">
  <article id="post-js面试题" class="article article-type-post" itemscope itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      
        
  
    <h1 class="article-title" itemprop="name">
      js面试题
    </h1>
  

      
      <div class="article-meta">
        <span class="article-date">
    <i class="icon icon-calendar-check"></i>
	<a href="/blog/2023/11/29/js%E9%9D%A2%E8%AF%95%E9%A2%98/" class="article-date">
	  <time datetime="2023-11-29T15:37:30.000Z" itemprop="datePublished">2023-11-29</time>
	</a>
</span>
        
  <span class="article-category">
    <i class="icon icon-folder"></i>
    <a class="article-category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
  </span>

        

        

        <span class="post-comment"><i class="icon icon-comment"></i> <a href="/blog/2023/11/29/js%E9%9D%A2%E8%AF%95%E9%A2%98/#comments" class="article-comment-link">评论</a></span>
        
      </div>
    </div>
    <div class="article-entry marked-body" itemprop="articleBody">
      
        <h3 id="1、防抖和节流"><a href="#1、防抖和节流" class="headerlink" title="1、防抖和节流"></a>1、防抖和节流</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 防抖：当持续触发一个事件时，在n秒内，事件没有再次触发，此时才会执行回调；如果n秒内，又触发了事件，就重新计时</span></span><br><span class="line"><span class="comment">// 使用场景：登录按钮，提交按钮，防止不断请求资源；监听resize触发时， 不断的调整浏览器窗口大小会不断触发resize，使用防抖可以让其只执行一次</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 实现原理：防抖就是闭包的应用场景</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">let</span> timer</span><br><span class="line">	<span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 重复调用，重新计算倒计时，所以需要先清楚定时器</span></span><br><span class="line">		<span class="built_in">clearTimeout</span>(timer)</span><br><span class="line">		timer = <span class="built_in">setTimeout</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">            <span class="built_in">console</span>.log(<span class="string">&#x27;防抖&#x27;</span>)</span><br><span class="line">        &#125;, <span class="number">3000</span>)</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> b = <span class="keyword">new</span> fn()</span><br><span class="line">b()</span><br><span class="line">b()</span><br><span class="line">b() <span class="comment">// 连续调用三次，函数里面的 console.log() 只会执行一次</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 节流：持续触发一个事件，每隔一段事件触发一次</span></span><br><span class="line"><span class="comment">// 应用场景：监听滚动事件，屏幕尺寸变化</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 实现原理：</span></span><br><span class="line"><span class="comment">// 无论点击多少次，只会在2秒后执行一次</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">let</span> timer</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> <span class="title">jieliu</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (!timer) &#123;</span><br><span class="line">        timer = <span class="built_in">setTimeout</span> (<span class="function">() =&gt;</span> &#123;</span><br><span class="line">          <span class="built_in">console</span>.log(<span class="string">&#x27;节流&#x27;</span>)</span><br><span class="line">          <span class="built_in">clearTimeout</span>(timer)</span><br><span class="line">          timer = <span class="literal">null</span></span><br><span class="line">        &#125;, <span class="number">2000</span>)</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<h3 id="2、前端八股文-http-和-https"><a href="#2、前端八股文-http-和-https" class="headerlink" title="2、前端八股文: http 和 https"></a>2、前端八股文: http 和 https</h3><blockquote>
<p><strong>一、http：</strong>超文本传输协议，信息是明文传输，连接简单，是无状态的（无状态指：协议对于事务处理没有记忆功能，服务器不知道客户端是什么状态。简单点来说，就是服务器不知道客户端已经请求过相同的东西，只要请求，服务端就会响应），默认端口号是 80</p>
</blockquote>
<blockquote>
<p><strong>二、https：</strong>具有安全性的 ssl 加密传输协议，可防止数据在传输过程中被窃取，改变，确保数据的完整性，默认端口号是 443</p>
</blockquote>
<h3 id="3、前端八股文：-TCP-的三次握手"><a href="#3、前端八股文：-TCP-的三次握手" class="headerlink" title="3、前端八股文： TCP 的三次握手"></a>3、前端八股文： TCP 的三次握手</h3><blockquote>
<p><strong>为什么需要三次握手：</strong>TCP 的三次握手是浏览器和服务器连接的方式，目的是为了二者能建立连接，便于后续的数据传输</p>
</blockquote>
<blockquote>
<p><strong>第一次握手：</strong>客户端向服务器发起建立连接的请求，等待服务器的确认</p>
</blockquote>
<blockquote>
<p><strong>第二次握手：</strong>服务器通知客户端，已接受客户端的请求，并向客户端发起建立连接的请求</p>
</blockquote>
<blockquote>
<p><strong>第三次握手：</strong>客户端通知服务端同意建立连接</p>
</blockquote>
<blockquote>
<p>完成三次握手后，客户端和服务端才开始传输数据</p>
</blockquote>
<blockquote>
<p><strong>为什么是三次握手而不是两次握手？</strong>在网络拥堵的情况下，客户端可能会发送多个报文，就可能导致客户端接受到的是历史连接，进而导致连接错误，所以才会有第三次握手，因为在第三次握手时，客户端会根据自身的上下文，判断这是一个历史连接（序列号过期或者超时），从而告诉服务器终止本次连接</p>
</blockquote>
<h3 id="4、前端八股文：-TCP-四次挥手"><a href="#4、前端八股文：-TCP-四次挥手" class="headerlink" title="4、前端八股文： TCP 四次挥手"></a>4、前端八股文： TCP 四次挥手</h3><blockquote>
<p><strong>第一次挥手：</strong>客户端向服务器发送断开连接的请求</p>
</blockquote>
<blockquote>
<p><strong>第二次挥手：</strong>服务器接收客户端发送过来的请求并向客户端发送应答信息</p>
</blockquote>
<blockquote>
<p><strong>第三次挥手：</strong>服务器向客户端发送确认断开请求</p>
</blockquote>
<blockquote>
<p><strong>第四次挥手：</strong>客户端接收服务器断开连接的请求，并且服务器发送确认断开请求，至此，客户端与服务端之间的请求已被断开</p>
</blockquote>
<h3 id="5、前端八股文：-http-请求跨域问题"><a href="#5、前端八股文：-http-请求跨域问题" class="headerlink" title="5、前端八股文： http 请求跨域问题"></a>5、前端八股文： http 请求跨域问题</h3><blockquote>
<p><strong>跨域的原理：</strong>跨域主要是因为浏览器的同源策略导致的，协议，域名，端口号不同，都会出现跨域</p>
</blockquote>
<blockquote>
<p><strong>解决跨域的方案：</strong></p>
</blockquote>
<pre><code>&gt; 1、jsonp：ajax 请求受同源策略影响，不允许进行跨域请求，而 script 标签 src 属性中的链 接却可以访问跨域的 js 脚本，利用这个特性，服务端不再返回 JSON 格式的数据，而是 返回一段调用某个函数的 js 代码，在 src 中进行了调用，这样实现了跨域。缺点：只支持 get 请求

&gt; 2、proxy 代理：通过服务器设置代理</code></pre>
<h3 id="6、前端八股文-cookie、sessionStorage、localStorage-的区别"><a href="#6、前端八股文-cookie、sessionStorage、localStorage-的区别" class="headerlink" title="6、前端八股文: cookie、sessionStorage、localStorage 的区别"></a>6、前端八股文: cookie、sessionStorage、localStorage 的区别</h3><blockquote>
<p>cookie数据大小不能超过4k；sessionStorage和localStorage的存储比cookie大得多，可以达到5M+</p>
</blockquote>
<blockquote>
<p>cookie设置的过期时间之前一直有效；localStorage永久存储，浏览器关闭后数据不丢失除非主动删除数据,sessionStorage数据在当前浏览器窗口关闭后自动删除</p>
</blockquote>
<blockquote>
<p>cookie的数据会自动的传递到服务器；sessionStorage和localStorage数据保存在本地</p>
</blockquote>
<h3 id="7、前端八股文：从输入-URL-到页面加载的全过程"><a href="#7、前端八股文：从输入-URL-到页面加载的全过程" class="headerlink" title="7、前端八股文：从输入 URL 到页面加载的全过程"></a>7、前端八股文：从输入 URL 到页面加载的全过程</h3><blockquote>
<p><strong>1、在浏览器中输入 URL</strong></p>
</blockquote>
<blockquote>
<p><strong>2、查找缓存：</strong>浏览器先查看浏览器缓存-系统缓存-路由缓存中是否有该地址页面，如果有则显示页面内容。如果没有则进行下一步</p>
</blockquote>
<blockquote>
<p><strong>3、DNS域名解析：</strong>浏览器向DNS服务器发起请求，解析该URL中的域名对应的IP地址</p>
</blockquote>
<blockquote>
<p><strong>4、建立TCP连接：</strong>解析出IP地址后，根据IP地址和默认80端口，和服务器建立TCP连接</p>
</blockquote>
<blockquote>
<p><strong>5、发起HTTP请求：</strong>浏览器发起读取文件的HTTP请求，该请求报文作为TCP三次握手的第三次数据发送给服务器</p>
</blockquote>
<blockquote>
<p><strong>6、服务器响应请求并返回结果：</strong>服务器对浏览器请求做出响应，并把对应的html文件发送给浏览器</p>
</blockquote>
<blockquote>
<p><strong>7、关闭TCP连接：</strong>通过四次挥手释放TCP连接</p>
</blockquote>
<blockquote>
<p><strong>8、浏览器渲染：</strong>客户端（浏览器）解析HTML内容并渲染出来</p>
</blockquote>
<blockquote>
<p><strong>9、JS引擎解析过程：</strong>调用JS引擎执行JS代码</p>
</blockquote>
<h3 id="7、前端八股文：重排和重绘"><a href="#7、前端八股文：重排和重绘" class="headerlink" title="7、前端八股文：重排和重绘"></a>7、前端八股文：重排和重绘</h3><blockquote>
<p><strong>1、重排（回流）：</strong>因为 DOM 元素的变化导致页面布局会发生变化，浏览器需要重新计算元素的位置，重新生成布局就叫做重排</p>
</blockquote>
<blockquote>
<p><strong>2、重绘：</strong>当一个元素的外观发生了变化，但是布局没有改变，将变化的外观重新渲染出来就叫做重绘</p>
</blockquote>
<blockquote>
<p><strong>注意点: 重绘不一定会发生重排，但是重排一定会发生重绘</strong></p>
</blockquote>
<blockquote>
<p>3、添加、删除、更新DOM节点；通过display: none隐藏一个DOM节点-触发重排和重绘；通过visibility: hidden隐藏一个DOM节点-只触发重绘，因为没有几何变化；移动或者给页面中的DOM节点添加动画；添加一个样式表，调整样式属性；用户行为，例如调整窗口大小，改变字号，或者滚动。</p>
</blockquote>
<blockquote>
<p><strong>3、如何避免发生重排和重绘：</strong>减少直接操作dom元素，改用className用于控制；如果需要创建多个DOM节点，可以使用DocumentFragment创建完后一次性的加入document；不要把 DOM 结点的属性值放在一个循环里当成循环里的变量；</p>
</blockquote>
<h3 id="前端八股文：浏览器的缓存机制，强缓存和协商缓存"><a href="#前端八股文：浏览器的缓存机制，强缓存和协商缓存" class="headerlink" title="前端八股文：浏览器的缓存机制，强缓存和协商缓存"></a>前端八股文：浏览器的缓存机制，强缓存和协商缓存</h3><blockquote>
<p><strong>1、浏览器的缓存机制：</strong>浏览器每次发起请求，都会先在浏览器缓存中查找该请求的结果以及缓存标识；浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中。缓存过程分为 <strong>强缓存</strong> 和 <strong>协商缓存</strong></p>
</blockquote>
<blockquote>
<p><strong>2、强缓存</strong>：就是向浏览器缓存查找该请求结果，并根据该结果的缓存规则来决定是否使用该缓存结果的过程</p>
</blockquote>
<blockquote>
<p><strong>3、协商缓存：</strong>协商缓存就是强制缓存失效后，浏览器携带缓存标识向服务器发起请求，由服务器根据缓存标识决定是否使用缓存的过程</p>
</blockquote>
<h3 id="js-的数据类型即区别"><a href="#js-的数据类型即区别" class="headerlink" title="js 的数据类型即区别"></a>js 的数据类型即区别</h3><blockquote>
<p><strong>js 的类型：</strong>包括基本数据类型和引用数据类型</p>
</blockquote>
<blockquote>
<p><strong>基本数据类型：</strong>Number(数字),String(字符串),Boolean(布尔),Symbol(符号),null(空),undefined(未定义)在内存中占据固定大小，保存在栈内存中</p>
</blockquote>
<blockquote>
<p><strong>引用数据类型：</strong>Object(对象)、Function(函数)。其他还有Array(数组)、Date(日期)、RegExp(正则表达式)、特殊的基本包装类型(String、Number、Boolean) 以及单体内置对象(Global、Math)等 引用类型的值是对象 保存在堆内存中，栈内存存储的是对象的变量标识符以及对象在堆内存中的存储地址</p>
</blockquote>
<h3 id="js-类型检测"><a href="#js-类型检测" class="headerlink" title="js 类型检测"></a>js 类型检测</h3><blockquote>
<p><strong>typeof：</strong>快速区分基本数据类型，但是不能区分 Object, Array, null，因为都是返回 object</p>
</blockquote>
<blockquote>
<p><strong>instanceof：</strong>能够区分Array、Object和Function，Number，Boolean，String基本数据类型不能判断</p>
</blockquote>
<blockquote>
<p><strong>constructor：</strong></p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log((<span class="number">2</span>).constructor === <span class="built_in">Number</span>); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log((<span class="literal">true</span>).constructor === <span class="built_in">Boolean</span>); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log((<span class="string">&#x27;str&#x27;</span>).constructor === <span class="built_in">String</span>); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(([]).constructor === <span class="built_in">Array</span>); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log((<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;).constructor === <span class="built_in">Function</span>); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log((&#123;&#125;).constructor === <span class="built_in">Object</span>); <span class="comment">// true</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>Object.prototype.toString.call()：</strong>既可以检测基本数据类型，也可以检测复杂数据类型。如：toString.call(1) =&gt; [object number]；toString.call({}) =&gt; [object object]</p>
</blockquote>
<h3 id="var、let、const"><a href="#var、let、const" class="headerlink" title="var、let、const"></a>var、let、const</h3><blockquote>
<p><strong>三者区别：</strong>var、let 可以用来定义变量，const 只能用来定义常量，并且使用时必须赋值，赋值后不能更改；var 存在变量提升，可以先使用后声明，var声明的变量会挂载到window上；var 允许重复声明一个变量，let、const 则不允许; let 存在暂时性死区问题</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// var 变量声明的提升</span></span><br><span class="line"><span class="built_in">console</span>.log(a) <span class="comment">// undefined</span></span><br><span class="line"><span class="keyword">var</span> a = <span class="number">1</span></span><br><span class="line"><span class="built_in">console</span>.log(a) <span class="comment">// 1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 等价于</span></span><br><span class="line"><span class="keyword">var</span> a;</span><br><span class="line"><span class="built_in">console</span>.log(a) <span class="comment">// undefined</span></span><br><span class="line">a = <span class="number">1</span>;</span><br><span class="line"><span class="built_in">console</span>.log(a) <span class="comment">//1</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="number">1</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Fn</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> a = <span class="number">2</span>;</span><br><span class="line">  <span class="built_in">console</span>.log(a)</span><br><span class="line">&#125;</span><br><span class="line">Fn() <span class="comment">// 2 (修改局部变量的值，不回对全局变量造成影响)</span></span><br><span class="line"><span class="built_in">console</span>.log(a) <span class="comment">// 1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// var 可以重复声明变量，后面的值会覆盖前面的值</span></span><br><span class="line"><span class="keyword">var</span> a = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">var</span> a = <span class="number">2</span>;</span><br><span class="line"><span class="built_in">console</span>.log(a) <span class="comment">// a</span></span><br><span class="line"><span class="comment">// 等价于</span></span><br><span class="line"><span class="keyword">var</span> a</span><br><span class="line">a = <span class="number">1</span>;</span><br><span class="line">a = <span class="number">2</span></span><br><span class="line"><span class="built_in">console</span>.log(a)</span><br><span class="line"></span><br><span class="line"><span class="comment">// let 块级作用域</span></span><br><span class="line"><span class="keyword">if</span>(<span class="literal">true</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> a = <span class="number">1</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">console</span>.log(a) <span class="comment">// undefined (let 声明的变量只能在当前块中能访问，而且不会存在变量声明的提升)</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// let 暂时性死区</span></span><br><span class="line"><span class="keyword">var</span> a = <span class="number">1</span></span><br><span class="line"><span class="keyword">if</span>(<span class="literal">true</span>) &#123;</span><br><span class="line">  a = <span class="number">2</span></span><br><span class="line">  <span class="built_in">console</span>.log(a) <span class="comment">//  Cannot access &#x27;c&#x27; before initialization (解析：let 声明块级作用域，必须先声明，再使用，否则报错，因为不存在变量提升)</span></span><br><span class="line">  <span class="keyword">let</span> a = <span class="number">3</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="闭包"><a href="#闭包" class="headerlink" title="闭包"></a>闭包</h3><blockquote>
<p><strong>存在的意义：</strong>可以间接的访问函数内部的变量</p>
</blockquote>
<blockquote>
<p><strong>什么是闭包：</strong>函数内嵌套一个函数，嵌套的函数可以访问外层函数作用域中的变量，导致函数的作用域不会被销毁</p>
</blockquote>
<blockquote>
<p><strong>闭包的用途：</strong>模仿块级作用域；封装私有化变量；防止变量被回收；匿名自执行函数</p>
</blockquote>
<blockquote>
<p><strong>优缺点：</strong>优点：延长局部变量的生命周期；缺点：会导致函数的变量一直保存在内存中，过多的闭包可能导致内存泄漏；<strong>如何解决内存泄漏：</strong>退出函数之前，将不使用的局部变量赋值为null；避免变量的循环引用；</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 会导致内存泄漏</span></span><br><span class="line"><span class="built_in">window</span>.onload = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">var</span> el = <span class="built_in">document</span>.getElementById(<span class="string">&#x27;id&#x27;</span>)</span><br><span class="line">	el.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">		alert(el.id)</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 解决</span></span><br><span class="line"><span class="built_in">window</span>.onload = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="keyword">var</span> el = <span class="built_in">document</span>.getElementById(<span class="string">&#x27;id&#x27;</span>)</span><br><span class="line">	<span class="keyword">var</span> id = el.id <span class="comment">// 接触循环引用</span></span><br><span class="line">	el.onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">		alert(id)</span><br><span class="line">	&#125;</span><br><span class="line">	el = <span class="literal">null</span>  <span class="comment">// 清除不使用的变量</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>如何检测内存泄漏：</strong>使用谷歌浏览器开发者工具中的Memory进行快照对比</p>
</blockquote>
<h3 id="js-继承的方式"><a href="#js-继承的方式" class="headerlink" title="js 继承的方式"></a>js 继承的方式</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">方式一：构造函数法（经典继承）</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Futer</span>(<span class="params">name</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">this</span>.name = name;</span><br><span class="line">  <span class="built_in">this</span>.func = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="built_in">this</span>.name)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">sub</span>(<span class="params">name, age</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 通过下面的三种方式改变 this 指向从而实现继承</span></span><br><span class="line">  Futer.call(<span class="built_in">this</span>, name);</span><br><span class="line">  <span class="comment">// Futer.bind(this, name);</span></span><br><span class="line">  <span class="comment">// Futer.apply(this, [name]);</span></span><br><span class="line">  <span class="built_in">this</span>.age = age;</span><br><span class="line">  <span class="built_in">this</span>.func()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">sub(<span class="string">&#x27;张三&#x27;</span>, <span class="number">18</span>) <span class="comment">// 结果：张三</span></span><br><span class="line"></span><br><span class="line">方式二：对象冒充</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">sub</span>(<span class="params">name, age</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">this</span>.fn = Futer</span><br><span class="line">  <span class="built_in">this</span>.fn(name)</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="built_in">this</span>.name)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">方式三：组合继承的方式（也叫原型链继承）</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Futer</span>(<span class="params">name</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">this</span>.name = name</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">sub</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line"></span><br><span class="line">sub.prototype = <span class="keyword">new</span> Futer(<span class="string">&#x27;张三&#x27;</span>)</span><br><span class="line"><span class="keyword">var</span> subObj = <span class="keyword">new</span> sub()</span><br><span class="line"></span><br><span class="line"><span class="comment">// 继承了其它构造函数的属性</span></span><br><span class="line">subObj.name <span class="comment">// 张三</span></span><br></pre></td></tr></table></figure>


<h3 id="this-的指向"><a href="#this-的指向" class="headerlink" title="this 的指向"></a>this 的指向</h3><blockquote>
<p>作为普通函数执行时，this指向window</p>
</blockquote>
<blockquote>
<p>当函数作为对象的方法被调用时，this就会指向该对象</p>
</blockquote>
<blockquote>
<p>构造器调用，this指向返回的这个对象</p>
</blockquote>
<blockquote>
<p>箭头函数的 this 指向最近的 this</p>
</blockquote>
<blockquote>
<p>改变 this 指向的方法：call，apply，bind</p>
</blockquote>
<h3 id="call-apply-bind的区别"><a href="#call-apply-bind的区别" class="headerlink" title="call,apply,bind的区别"></a>call,apply,bind的区别</h3><blockquote>
<p>call和bind的参数是依次传参，一一对应的</p>
</blockquote>
<blockquote>
<p>但apply只有两个参数，第一个参数是函数的this，第二个参数为数组；</p>
</blockquote>
<blockquote>
<p>call和apply都是对函数进行直接调用（同步），而bind方法返回的仍是一个函数（异步执行）；</p>
</blockquote>
<h3 id="原型和原型链"><a href="#原型和原型链" class="headerlink" title="原型和原型链"></a>原型和原型链</h3><blockquote>
<p> <a target="_blank" rel="noopener" href="https://yuluobk.gitee.io/blog/2020/12/15/%E5%8E%9F%E5%9E%8B%E9%93%BE/">原型图查看</a></p>
</blockquote>
<blockquote>
<p><strong>原型关系：</strong>每个构造函数都有显式原型 prototype；每个实例都有隐式原型 __proto__；实例的隐式原型（_ proto_）指向构造函数的 prototype；</p>
</blockquote>
<blockquote>
<p><strong>原型：</strong> 在 JS 中，每当定义一个对象（函数也是对象）时，对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性，这个属性指向函数的原型对象</p>
</blockquote>
<blockquote>
<p><strong>原型链：</strong>函数的原型对象的constructor属性默认指向函数本身，其实例对象也有<strong>proto__属性，指向原型对象，而上一层的原型对象的结构依然类似。因此可以利用__proto__一直指向Object的原型对象上，而Object原型对象用Object.prototype.</strong> proto__ = null表示原型链顶端。如此形成了js的原型链继承。</p>
</blockquote>
<h3 id="EventLoop-事件循环"><a href="#EventLoop-事件循环" class="headerlink" title="EventLoop 事件循环"></a>EventLoop 事件循环</h3><blockquote>
<p>JS是单线程的，为了防止一个函数执行时间过长阻塞后面的代码，所以会先将同步代码压入执行栈中，依次执行，将异步代码推入异步队列，异步队列又分为宏任务队列和微任务队列，因为宏任务队列的执行时间较长，所以微任务队列要优先于宏任务队列 <strong>（先同步后异步，先微任务再宏任务）</strong>。微任务队列的代表就是，<strong>Promise.then，MutationObserver</strong>，宏任务的话就是<strong>setImmediate setTimeout setInterval</strong></p>
</blockquote>
<blockquote>
<p><strong>运行机制：</strong>代码开始执行的时候，任务先进入执行栈(call back)中，如果是同步任务，则执行该任务，并输出结果，该任务出栈，执行栈开始执行下一个任务。执行栈在执行时，如果发现该任务是宏任务，那么该宏任务进入宏任务队列，如果是微任务，那么进入微任务队列，当执行栈的任务执行完，执行栈为空时，首先会来到微任务队列中，将微任务放到执行栈中执行，如果在微任务执行的过程中添加微任务，那么添加的微任务也会在本次循环中执行，即在事件循环前调用。当微任务也执行完时，事件循环判断到执行栈和微任务队列都为空，那么将循环到宏任务队列，将宏任务放入执行栈中执行，直到宏任务也执行完，代码就执行完毕</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">setTimeout</span>(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; <span class="comment">// 异步任务中的微任务</span></span><br><span class="line">	<span class="built_in">console</span>.log(<span class="string">&#x27;timeout1&#x27;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123; <span class="comment">// new promise 属于同步任务</span></span><br><span class="line">	<span class="built_in">console</span>.log(<span class="string">&#x27;promise&#x27;</span>)</span><br><span class="line">	<span class="keyword">for</span> (<span class="keyword">var</span> i=<span class="number">0</span>; i&lt;<span class="number">100</span>; i++ )&#123;</span><br><span class="line">		id = <span class="number">99</span> &amp;&amp; resolve()</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="built_in">console</span>.log(<span class="string">&#x27;promise2&#x27;</span>)</span><br><span class="line">&#125;).then(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; <span class="comment">// then 属于异步任务中的微任务</span></span><br><span class="line">	<span class="built_in">console</span>.log(<span class="string">&#x27;then1&#x27;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">&#x27;global&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 输出结果：promise, promise2, global, then1, timeout1</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">async1</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">   <span class="built_in">console</span>.log(<span class="string">&#x27;async1 start&#x27;</span>);</span><br><span class="line">    <span class="keyword">await</span> async2();</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;async1 end&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">async2</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;async2&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">&#x27;script start&#x27;</span>);</span><br><span class="line">async1();</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">&#x27;script end&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 输出顺序：script start，async1 start，async2，script end，async1 end</span></span><br></pre></td></tr></table></figure>

<h3 id="null-和-undefined-的区别？"><a href="#null-和-undefined-的区别？" class="headerlink" title="null 和 undefined 的区别？"></a>null 和 undefined 的区别？</h3><blockquote>
<p><strong>undefined：</strong>代表未定义，一般变量声明了但还没有定义的时候会返回 undefined，转为数值是 NaN  <code>var a; console.log(a) // 结果：undefined</code></p>
</blockquote>
<blockquote>
<p><strong>null：</strong>代表空对象，null主要用于赋值给一些可能会返回对象的变量，作为初始化，转为数值为0</p>
</blockquote>
<h3 id="为什么-0-1-0-2-0-3"><a href="#为什么-0-1-0-2-0-3" class="headerlink" title="为什么 0.1 + 0.2 !== 0.3 ?"></a>为什么 0.1 + 0.2 !== 0.3 ?</h3><blockquote>
<p>因为计算存储数据是通过二进制的方式存储的，0.1 的二进制为：0.000010101010100001…. ; 0.2 的二进制为：0.0000001717828383….. 所以不等</p>
</blockquote>
<blockquote>
<p>解决方法：对于这个问题，一个直接的解决方法就是设置一个误差范围，通常称为“机器精度”。对JavaScript来说，这个值通常为2-52，在ES6中，提供了Number.EPSILON属性，而它的值就是2-52，只要判断0.1+0.2-0.3是否小于Number.EPSILON，如果小于，就可以判断为0.1+0.2 ===0.3</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">numberepsilon</span>(<span class="params">arg1,arg2</span>)</span>&#123;                   </span><br><span class="line">  <span class="keyword">return</span> <span class="built_in">Math</span>.abs(arg1 - arg2) &lt; <span class="built_in">Number</span>.EPSILON;        </span><br><span class="line">&#125;        </span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(numberepsilon(<span class="number">0.1</span> + <span class="number">0.2</span>, <span class="number">0.3</span>)); <span class="comment">// true</span></span><br></pre></td></tr></table></figure>

<h3 id="object-assign-和扩展运算符是深拷贝还是浅拷贝？"><a href="#object-assign-和扩展运算符是深拷贝还是浅拷贝？" class="headerlink" title="object.assign() 和扩展运算符是深拷贝还是浅拷贝？"></a>object.assign() 和扩展运算符是深拷贝还是浅拷贝？</h3><blockquote>
<p>两者都是浅拷贝</p>
</blockquote>
<h3 id="深拷贝和浅拷贝的方式"><a href="#深拷贝和浅拷贝的方式" class="headerlink" title="深拷贝和浅拷贝的方式"></a>深拷贝和浅拷贝的方式</h3><blockquote>
<p>浅拷贝：只是拷贝了内存地址，修改一个对象的值，原对象的值也会跟着修改（因为都是指向原对象的地址）： for .. in ，将对象的第一层属性复制到另一个对象中；Object.assign()，lodash 库中的clone()方法</p>
</blockquote>
<blockquote>
<p>深拷贝：（将对象的属性进行递归复制，新对象和原对象不共享内存）使用JSON.stringify()（把对象转成字符串），再JSON.parse()（把字符串转成新的对象），lodash 库中的 cloneDeep() 方法</p>
</blockquote>
<blockquote>
<p>深拷贝的应用场景：需要对象中的数据，但是又不想改变原对象，此时可以使用深拷贝；vuex 中存在要给对象，多个页面都需要使用这个对象，然后进行一些操作，此时，为了防止对原对象的影响，需要使用深拷贝</p>
</blockquote>
<blockquote>
<p>浅拷贝的应用场景：使用Object.assign()合并对象</p>
</blockquote>
<h3 id="如果new一个箭头函数的会怎么样"><a href="#如果new一个箭头函数的会怎么样" class="headerlink" title="如果new一个箭头函数的会怎么样"></a>如果new一个箭头函数的会怎么样</h3><blockquote>
<p>箭头函数是ES6中的提出来的，它没有prototype，也没有自己的this指向，更不可以使用arguments参数，所以不能New一个箭头函数。</p>
</blockquote>
<blockquote>
<p><strong>new 操作符的实现步骤：</strong>1、创建一个对象；2、设置原型，将对象的原型设置为函数的 prototype 对象（也就是将对象的__proto__属性指向构造函数的prototype属性）；3、让函数的 this 指向这个对象，执行构造函数的代码（也就是为这个对象添加属性和方法）；4、 返回新的对象；在第二步和第三步，箭头函数是没法执行的</p>
</blockquote>
<h3 id="箭头函数和普通函数的区别"><a href="#箭头函数和普通函数的区别" class="headerlink" title="箭头函数和普通函数的区别"></a>箭头函数和普通函数的区别</h3><blockquote>
<p>箭头函数没有自己的 this</p>
</blockquote>
<blockquote>
<p>箭头函数继承来的 this 指向不会发生改变</p>
</blockquote>
<blockquote>
<p>call(), apply(), bind() 无法改变箭头函数 this 都指向</p>
</blockquote>
<blockquote>
<p>箭头函数不能作为构造函数，没有 prototype，没有自己的 arguments 参数（访问到的 arguments 参数是外层函数 arguments 的值</p>
</blockquote>
<h3 id="扩展运算符的作用以及使用场景？"><a href="#扩展运算符的作用以及使用场景？" class="headerlink" title="扩展运算符的作用以及使用场景？"></a>扩展运算符的作用以及使用场景？</h3><blockquote>
<p>对象的扩展运算符：取出对象中所有可遍历属性，拷贝到当前对象；数组扩展运算符：将数组转为用逗号相隔的参数序列，每次只能展开一层数组<code>console.log(...[1,2,3]) =&gt; 1,2,3; console.log(...[1,[2,3],4]) =&gt; 1,[2,3],4</code>；将字符串转为真正的数组 <code>[...&#39;he&#39;] =&gt; [&#39;h&#39;,&#39;e&#39;]</code></p>
</blockquote>
<h3 id="call-和-apply"><a href="#call-和-apply" class="headerlink" title="call() 和 apply()"></a>call() 和 apply()</h3><blockquote>
<p>两者都是改变 this 的指向，他们的区别就是传入参数的形式不同，apply() 接收两个参数，call() 接收的参数不固定</p>
</blockquote>
<h3 id="promise-解决了什么问题？"><a href="#promise-解决了什么问题？" class="headerlink" title="promise 解决了什么问题？"></a>promise 解决了什么问题？</h3><blockquote>
<p>请求一般都是异步的，如果想要拿到上一个请求的结果，作为下一个请求的参数，那么就必须是请求里面防止其它的请求，这样就会导致层层嵌套，自然就会出现一个回调地狱的问题。解决方式就是使用promise。promise本质上是给出了一种异步任务同步写法的解决方案（promise 的链式调用），然后才是解决回调地狱问题；</p>
</blockquote>
<h3 id="对于-promise-的理解"><a href="#对于-promise-的理解" class="headerlink" title="对于 promise 的理解"></a>对于 promise 的理解</h3><blockquote>
<p>promise 是异步编程的一个解决方案，避免回调地狱。Promise 实例有三种状态，pedding（进行中）resolved（已完成）rejected（已拒绝），状态一旦发生改变，状态就永远不会发生改变，不会受外界的影响。它的原型上定义了一个 then 方法，分别对应成功的回调和失败的回调</p>
</blockquote>
<h3 id="promise-的应用场景"><a href="#promise-的应用场景" class="headerlink" title="promise 的应用场景"></a>promise 的应用场景</h3><blockquote>
<p>场景一：多个请求结果合并在一起，比如：一个页面有多个请求，需要等所有的请求都返回数据后，再一起渲染(结合 promise.all())</p>
</blockquote>
<blockquote>
<p>使用 promise.all() 虽然能够等所有接口都返回结果再一起渲染，但是如果某个请求失败了，那么 promise.all() 则只会返回失败的 promise 的结果，这就导致了整个页面都无法渲染。所以，解决方法是，给出传入 promise.all() 中的每个 promise 都增加 catch() 方法，这样就能够在一个地方集中处理失败的逻辑，从而解决了 promise.all() 只返回失败的 promise 的结果的问题和整个页面无法渲染的问题</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//1.获取轮播数据列表</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getBannerList</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> axios&#123;...&#125;</span><br><span class="line">    .then(<span class="function"><span class="params">res</span> =&gt;</span> resolve(data), <span class="function">() =&gt;</span> reject(<span class="string">&#x27;接口报错了&#x27;</span>))</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//2.获取店铺列表</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getStoreList</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">   <span class="keyword">return</span> axios&#123;...&#125;.then(<span class="function"><span class="params">res</span> =&gt;</span> resolve(<span class="number">1</span>))</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//3.获取分类列表</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getCategoryList</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">   <span class="keyword">return</span> axios&#123;...&#125;.then(<span class="function"><span class="params">res</span> =&gt;</span> resolve(<span class="number">2</span>))</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">initLoad</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="comment">// loading.show() //加载loading</span></span><br><span class="line">    <span class="built_in">Promise</span>.all([getBannerList().catch(<span class="function"><span class="params">err</span> =&gt;</span> err),getStoreList().catch(<span class="function"><span class="params">err</span> =&gt;</span>err ),getCategoryList().catch(<span class="function"><span class="params">err</span> =&gt;</span>err )]).then(<span class="function"><span class="params">res</span>=&gt;</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(res) <span class="comment">// 结果：[&#x27;接口报错了&#x27;, 1, 2]</span></span><br><span class="line">    &#125;).catch(<span class="function"><span class="params">err</span>=&gt;</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(err)</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//数据初始化    </span></span><br><span class="line">initLoad()</span><br></pre></td></tr></table></figure>

<blockquote>
<p>场景二：合并处理错误(结合 promise.all())</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn1</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    reject(<span class="string">&#x27;错误了&#x27;</span>)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn2</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    resolve(<span class="number">1</span>)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过增加 catch() ，统一处理错误信息</span></span><br><span class="line"><span class="built_in">Promise</span>.all([fn1().catch(<span class="function"><span class="params">err</span> =&gt;</span> err), fn2().catch(err =&lt; err)]).then(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">  <span class="built_in">console</span>.log(res) <span class="comment">// [&#x27;错误了&#x27;, 1]</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<blockquote>
<p>场景三：图片请求超时(结合 promise.race())</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//请求某个图片资源</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">requestImg</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> p = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve, reject</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">var</span> img = <span class="keyword">new</span> Image();</span><br><span class="line">        img.onload = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">           resolve(img);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//img.src = &quot;https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg&quot;; 正确的</span></span><br><span class="line">        img.src = <span class="string">&quot;https://b-gold-cdn.xitu.io/v3/static/img/logo.a7995ad.svg1&quot;</span>;</span><br><span class="line">    &#125;);</span><br><span class="line">    <span class="keyword">return</span> p;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//延时函数，用于给请求计时</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">timeout</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> p = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve, reject</span>)</span>&#123;</span><br><span class="line">        <span class="built_in">setTimeout</span>(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">            reject(<span class="string">&#x27;图片请求超时&#x27;</span>);</span><br><span class="line">        &#125;, <span class="number">5000</span>);</span><br><span class="line">    &#125;);</span><br><span class="line">    <span class="keyword">return</span> p;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 接口在规定时间内返回数据，则 promise.race() 返回这个请求成功的接口数据；否则则会返回第二个函数的结果，从而实现了图片请求超时处理</span></span><br><span class="line"><span class="built_in">Promise</span></span><br><span class="line">.race([requestImg(), timeout()])</span><br><span class="line">.then(<span class="function"><span class="keyword">function</span>(<span class="params">results</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(results);</span><br><span class="line">&#125;)</span><br><span class="line">.catch(<span class="function"><span class="keyword">function</span>(<span class="params">reason</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(reason);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<blockquote>
<p>场景四：使用多重链式调用：数据量超大的接口回调处理<br>注意：链式调用的前提：必须将上一个 then 得到的 res return 出去，这样下一个 then() 才能接收到数据，否则数据是 undefined</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn1</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    reject(<span class="string">&#x27;错误了&#x27;</span>)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn2</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    resolve(<span class="number">1</span>)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过增加 catch() ，统一处理错误信息</span></span><br><span class="line"><span class="built_in">Promise</span>.all([fn1().catch(<span class="function"><span class="params">err</span> =&gt;</span> err), fn2().catch(err =&lt; err)]).then(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">  <span class="built_in">console</span>.log(res) <span class="comment">// [&#x27;错误了&#x27;, 1]</span></span><br><span class="line">  <span class="keyword">return</span> res;</span><br><span class="line">&#125;).then(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">  <span class="built_in">console</span>.log(res) <span class="comment">//  [&#x27;错误了&#x27;, 1]</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<blockquote>
<p>场景五：接口重试</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> axios(&#123;<span class="attr">url</span>: <span class="string">&#x27;&#x27;</span>,<span class="attr">method</span>: <span class="string">&#x27;post&#x27;</span>,<span class="attr">data</span>: &#123;&#125;&#125;).then(<span class="function"><span class="params">res</span> =&gt;</span> resolve(res))</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">timeOut</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">return</span> reject(<span class="string">&#x27;网络不佳&#x27;</span>)</span><br><span class="line">    &#125;, <span class="number">2000</span>)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn2</span>(<span class="params">count</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> i = <span class="number">0</span>;</span><br><span class="line">  <span class="keyword">while</span>(i &lt; count)&#123;</span><br><span class="line">    <span class="built_in">Promise</span>.race([fn().catch(), timeOut().catch()]).then(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">if</span>(res === <span class="string">&#x27;网络不佳&#x27;</span>) &#123;</span><br><span class="line">      i += <span class="number">1</span>；</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      i = <span class="number">0</span>;</span><br><span class="line">      <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span>(i===<span class="number">0</span>) <span class="built_in">console</span>.log(<span class="string">&#x27;接口正常请求&#x27;</span>)；</span><br><span class="line">  <span class="keyword">else</span> <span class="built_in">console</span>.log(<span class="string">&#x27;接口请求超时&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">fn2(<span class="number">3</span>) <span class="comment">// 重试3次</span></span><br></pre></td></tr></table></figure>

<h3 id="async-await-的理解"><a href="#async-await-的理解" class="headerlink" title="async/await 的理解"></a>async/await 的理解</h3><blockquote>
<p>async/await其实是Generator 的语法糖，它能实现的效果都能用then链来实现，它是为优化then链而开发出来的。async 函数返回的是一个 promise 对象，通过 await 阻塞后面的语句，直到接收到一个结果，代码才会往下执行</p>
</blockquote>
<h3 id="垃圾回收机制"><a href="#垃圾回收机制" class="headerlink" title="垃圾回收机制"></a>垃圾回收机制</h3><blockquote>
<p>javascript 具有自动垃圾回收机制，会定期对不再使用的变量，对象的内容进行释放，常见的方式有：<strong>标记清除</strong>，<strong>引用计数</strong></p>
</blockquote>
<blockquote>
<p><strong>如何减少垃圾回收：</strong>删除多余的变量；对象尽量复用，或者设置为 null；清空数组的时候，直接赋值为 [] 或者修改其长度为 0</p>
</blockquote>
<blockquote>
<p><strong>导致内存泄漏的情况：</strong>意外的全局变量：使用了为声明的变量，从而意外的创建了一个全局变量；被遗忘的计时器或者回调函数；闭包：不合理的使用闭包，从而导致变量一直保留在内存中</p>
</blockquote>
<h3 id="new操作符具体干了什么？"><a href="#new操作符具体干了什么？" class="headerlink" title="new操作符具体干了什么？"></a>new操作符具体干了什么？</h3><blockquote>
<p>创建一个新的空对象，将新对象的 <strong>poroto</strong> 属性指向构造函数的 protorype 属性（即，指向构造函数的原型对象）；将构造函数的 this 指向该对象，将构造函数的方法和属性加入到this的引用中，最后返回 this</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> Person = <span class="function"><span class="keyword">function</span>(<span class="params">name,age</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.name = name</span><br><span class="line"></span><br><span class="line">    <span class="built_in">this</span>.age = age</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">myNew</span>(<span class="params">fn,name,age</span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> obj = &#123;&#125; <span class="comment">//创建一个空对象</span></span><br><span class="line"></span><br><span class="line">    obj.__proto__ = fn.prototype <span class="comment">//将该对象的`__proto__`属性指向构造函数的`prototype`</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> result = fn.call(obj,name,age) <span class="comment">// 将构造函数的this指向该对象并执行构造函数</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">typeof</span> result === <span class="string">&#x27;object&#x27;</span> ? result : obj <span class="comment">// 返回</span></span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> person = myNew(Person,<span class="string">&#x27;Jack&#x27;</span>,<span class="number">18</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h3 id="js-事件处理机制-也叫-DOM-事件流"><a href="#js-事件处理机制-也叫-DOM-事件流" class="headerlink" title="js 事件处理机制(也叫 DOM　事件流)"></a>js 事件处理机制(也叫 DOM　事件流)</h3><blockquote>
<p>事件捕获：事件从window对象自上而下向目标节点传播的阶段，从最外层节点往下传递，直到最底层节点，依次触发事件</p>
</blockquote>
<blockquote>
<p>事件冒泡：事件从目标节点自下而上向window对象传播的阶段，从最底层节点向外层节点传递，依次触发事件</p>
</blockquote>
<blockquote>
<p>事件监听：真正的目标节点正在处理事件的阶段</p>
</blockquote>
<h3 id="js-延迟加载的方式"><a href="#js-延迟加载的方式" class="headerlink" title="js 延迟加载的方式"></a>js 延迟加载的方式</h3><blockquote>
<p>setTimeout()，将 js 脚本放到文档的最底部，动态创建 dom 方式，defer 属性，延迟脚本，立即下载，等页面解析完成后再执行;acync 属性，立即下载，立即执行</p>
</blockquote>
<h3 id="document-write-和-innerHtml-的区别？"><a href="#document-write-和-innerHtml-的区别？" class="headerlink" title="document.write 和 innerHtml 的区别？"></a>document.write 和 innerHtml 的区别？</h3><blockquote>
<p>document.write() 只能重绘整个页面；innerHtml 可以重绘一部分</p>
</blockquote>
<h3 id="遍历数组"><a href="#遍历数组" class="headerlink" title="遍历数组"></a>遍历数组</h3><blockquote>
<p>map(): 返回新的数组，当数组的值是基本数据类型（如：[1, 2, 3]）时，使用 map() 遍历数组，不回改变原数组；当数组是一个对象数组时，map() 遍历会修改原数组，解决方法，返回一个新的对象</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> a = [&#123;<span class="attr">a</span>: <span class="number">1</span>&#125;].map(<span class="function"><span class="params">item</span> =&gt;</span> &#123;</span><br><span class="line">  itme.b = <span class="number">2</span> <span class="comment">// 等价于： item = &#123;a: 1&#125;; item.b = 2;</span></span><br><span class="line">  <span class="keyword">return</span> item;</span><br><span class="line">&#125;) <span class="comment">// 这样遍历，会导致原数组也发生了改变（因为对象是引用类型，赋值操作相当于把对象的地址赋值给了其它变量，所以，它们都会指向元对象，所以修改一个，原对象也会发生更改）</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 正确的处理方法是: 创建一个新的对象，将元对象的属性和方法解构到新的对象中，然后返回新的对象</span></span><br><span class="line"><span class="keyword">const</span> a = [&#123;<span class="attr">a</span>: <span class="number">1</span>&#125;].map(<span class="function"><span class="params">item</span> =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    ...item, <span class="comment">// 扩展运算符属于深拷贝，所以不会影响元对象</span></span><br><span class="line">    b: <span class="number">2</span></span><br><span class="line">  &#125;;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<blockquote>
<p>filter(): 返回新的数组，不回修改原数组（无论是基本数据数组，还是对象数组，都不回）</p>
</blockquote>
<blockquote>
<p>forEach(): 不回返回新的数组，会修改原数组；设置 return 相当于 continue 使用，只用于控制是否跳出当前循环</p>
</blockquote>

      
    </div>
    <div class="article-footer">
      <!-- <blockquote class="mt-2x"> -->
  <!-- <ul class="post-copyright list-unstyled">
    
    <li class="post-copyright-link hidden-xs">
      <strong>本文链接：</strong>
      <a href="https://gitee.com/Yu-Luoboke/2023/11/29/js%E9%9D%A2%E8%AF%95%E9%A2%98/" title="js面试题" target="_blank" rel="external">https://gitee.com/Yu-Luoboke/2023/11/29/js%E9%9D%A2%E8%AF%95%E9%A2%98/</a>
    </li>
    
    <li class="post-copyright-license">
      <strong>版权声明： </strong> 本博客所有文章除特别声明外，均采用 <a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN协议</a> 许可协议。转载请注明出处！
    </li>
  </ul> -->
<!-- </blockquote> -->


<!-- <div class="panel panel-default panel-badger">
  <div class="panel-body">
    <figure class="media">
      <div class="media-left">
        <a href="http://yu-luoboke.gitee.io/blog" target="_blank" class="img-burn thumb-sm visible-lg">
          <img src="/blog/images/avatar.jpg" class="img-rounded w-full" alt="">
        </a>
      </div>
      <div class="media-body">
        <h3 class="media-heading"><a href="http://yu-luoboke.gitee.io/blog" target="_blank"><span class="text-dark">雨落</span><small class="ml-1x">前端开发-奋斗青年</small></a></h3>
        <div>前端经验总结。</div>
      </div>
    </figure>
  </div>
</div> -->


    </div>
  </article>
  
    

  
</div>

  <nav class="bar bar-footer clearfix" data-stick-bottom>
  <div class="bar-inner">
  
  <ul class="pager pull-left">
    
    <li class="prev">
      <a href="/blog/2023/11/29/css%E9%9D%A2%E8%AF%95%E9%A2%98/" title="css面试题"><i class="icon icon-angle-left" aria-hidden="true"></i><span>&nbsp;&nbsp;上一篇</span></a>
    </li>
    
    
    <li class="next">
      <a href="/blog/2023/11/29/%E9%9D%A2%E8%AF%95%E9%A2%98/" title="面试题"><span>下一篇&nbsp;&nbsp;</span><i class="icon icon-angle-right" aria-hidden="true"></i></a>
    </li>
    
    
  </ul>
  
  
  
  <div class="bar-right">
    
  </div>
  </div>
</nav>
  


</main>

  <footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
	
	
    <ul class="social-links">
    	
        <li><a href="http://yu-luoboke.gitee.io/blog" target="_blank" title="Github" ><i class="icon icon-github"></i></a></li>
        
    </ul>

    <div class="copyright">
    	
        &copy; 2024 lianghongming
        
        <div class="publishby">
        	Theme by <a href="https://gitee.com/Yu-Luoboke/blog" target="_blank"> blog </a>base on <a href="https://gitee.com/Yu-Luoboke/blog" target="_blank">pure</a>.
        </div>
    </div>
</footer>
  <script src="//cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>

<script src="/blog/js/plugin.min.js"></script>


<script src="/blog/js/application.js"></script>


    <script>
(function (window) {
    var INSIGHT_CONFIG = {
        TRANSLATION: {
            POSTS: '文章',
            PAGES: '页面',
            CATEGORIES: '分类',
            TAGS: '标签',
            UNTITLED: '(未命名)',
        },
        ROOT_URL: '/blog/',
        CONTENT_URL: '/blog/content.json',
    };
    window.INSIGHT_CONFIG = INSIGHT_CONFIG;
})(window);
</script>

<script src="/blog/js/insight.js"></script>






   









</body>
</html>